/*
 * Copyright(c) 2020-2100 万达信息股份有限公司 版权所有
 * WONDERS INFORMATION CO., LTD. ALL RIGHTS RESERVED.
 */

package com.wondersgroup.sqlengine;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.FutureTask;

/**
 * 配置类
 *
 * @author: huym
 * @date: 2021/1/22
 */
public class Configuration {

	private final ConcurrentHashMap<String, FutureTask<SqlTemplate>> templateCache = new ConcurrentHashMap();

	private transient boolean cacheTemplate;

	private Charset charset;

	public void setCacheTemplate(boolean cacheTemplate) {
		this.cacheTemplate = cacheTemplate;
	}

	public void setCharset(Charset charset) {
		this.charset = charset;
	}

	public Configuration() {
		this(true, Charset.defaultCharset());
	}

	public Configuration(boolean cacheTemplate, Charset charset) {
		super();
		this.cacheTemplate = cacheTemplate;
		this.charset = charset;
	}

	public SqlTemplate getTemplate(final String content) {
		if (this.cacheTemplate) {
			FutureTask<SqlTemplate> futureTask = this.templateCache.get(content);
			if (futureTask == null) {
//				FutureTask<SqlTemplate> innerFutureTask = new FutureTask(new Callable<SqlTemplate>() {
//							public SqlTemplate call() throws Exception {
//								return this.innerCreateTemplate(content);
//							}
//						});
				FutureTask<SqlTemplate> innerFutureTask = new FutureTask(() -> this.innerCreateTemplate(content));
				futureTask = templateCache.putIfAbsent(content, innerFutureTask);
				if (futureTask == null) {
					innerFutureTask.run();
					futureTask = innerFutureTask;
				}
			}
			try {
				return futureTask.get();
			} catch (Exception e) {
				this.templateCache.remove(content);
				throw new RuntimeException(e);
			}
		}
		return this.innerCreateTemplate(content);
	}

	public SqlTemplate getTemplate(InputStream in) throws IOException {
		return this.getTemplate(this.innerReaderContent(in));
	}

	public SqlTemplate getTemplate(File file) throws IOException {
		return this.getTemplate(new FileInputStream(file));
	}

	private SqlTemplate innerCreateTemplate(String content) {
		return new SqlTemplate.SqlTemplateBuilder(this, content).build();
	}

	private String innerReaderContent(InputStream in) throws IOException {
		StringBuilder sb = new StringBuilder(in.available());
		InputStreamReader inputStreamReader = null;
		BufferedReader bufferedReader = null;
		try {
			inputStreamReader = new InputStreamReader(new BufferedInputStream(in), charset);
			bufferedReader = new BufferedReader(inputStreamReader);
			String line;
			while ((line = bufferedReader.readLine()) != null) {
				sb.append(line);
			}
		} finally {
			if (bufferedReader!=null) {
				bufferedReader.close();
			}
			if (inputStreamReader!=null) {
				inputStreamReader.close();
			}
			if (in!=null) {
				in.close();
			}
		}
		return sb.toString();
	}

}